package com.example.beautymakeup.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.beautymakeup.config.DouyinConfig;
import com.example.beautymakeup.dao.OrderDao;
import com.example.beautymakeup.dao.ShopDao;
import com.example.beautymakeup.domain.Code;
import com.example.beautymakeup.domain.PageBean;
import com.example.beautymakeup.domain.Result;
import com.example.beautymakeup.dto.DouyinAuthDTO;
import com.example.beautymakeup.pojo.Order;
import com.example.beautymakeup.pojo.Shop;
import com.example.beautymakeup.service.DouyinAuthService;
import com.example.beautymakeup.service.OrderService;
import com.example.beautymakeup.utils.JwtUtil;
import com.example.beautymakeup.utils.TimeUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private DouyinConfig douyinConfig;

    @Autowired
    private DouyinAuthService douyinAuthService;

    @Override
    public Result queryDouyinOrder(String orderNo) throws Exception {
        // 使用抖音OAuth2.0 token
        DouyinAuthDTO authDTO = new DouyinAuthDTO();
        authDTO.setClientId(douyinConfig.getClientId());
        authDTO.setClientSecret(douyinConfig.getClientSecret());
        authDTO.setCode(douyinConfig.getAuthCode());
        String accessToken = douyinAuthService.exchangeAccessToken(authDTO);

        Map<String, Object> params = new HashMap<>();
        params.put("order_no", orderNo);
        String signature = generateSignature(params, douyinConfig.getClientSecret());
        params.put("sign", signature);
        params.put("access_token", accessToken);

        JSONObject result = null;
        int retryCount = 0;
        while (retryCount <= maxRetries) {
            try {
                String response = HttpUtil.get(douyinConfig.getOrderQueryUrl(), params);
                result = JSON.parseObject(response);
                break;
            } catch (Exception e) {
                if (retryCount == maxRetries) {
                    return new Result(Code.GET_ERR, "接口请求失败，重试次数已用尽");
                }
                Thread.sleep(1000);
                retryCount++;
            }
        }

        if (result.getInteger("code") == 0) {
            Order order = result.getObject("data", Order.class);
            return new Result(Code.GET_OK, "查询成功", order);
        }
        return new Result(Code.GET_ERR, result.getString("message"));
    }

    @Value("${douyin.max-retries:3}")
    private int maxRetries;

    private String generateSignature(Map<String, Object> params, String secret) {
        List<String> paramList = new ArrayList<>();
        params.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .forEach(entry -> paramList.add(entry.getKey() + "=" + entry.getValue()));
        String signStr = String.join("&", paramList) + "&secret=" + secret;
        return DigestUtils.sha256Hex(signStr);
    }

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private ShopDao shopDao;

    @Autowired
    private TimeUtil timeUtil;

    @Override
    public PageBean<Order> getByUserId(String token) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if (!"admin".equals(subject)) {
            List<Order> list = orderDao.getByUserId(Integer.parseInt(subject));
            for (Order o :
                    list) {
                String time = timeUtil.getTime(o.getDate());
                o.setDate(time);
            }
            PageBean<Order> pageBean = new PageBean<>();
            pageBean.setRows(list);
            return pageBean;
        }
        return null;
    }

    @Override
    public Order getByUid(String token, int uid) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if (!"admin".equals(subject)) {
            Order byUid = orderDao.getByUid(uid);
            byUid.setDate(timeUtil.getTime(byUid.getDate()));
            return byUid;
        }
        return null;
    }

    @Override
    public PageBean<Order> getAll(String token, int page, int size) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if ("admin".equals(subject)) {
            List<Order> list = orderDao.getAll((page - 1) * size, size);
            int allCount = orderDao.getAllCount();
            PageBean<Order> pageBean = new PageBean<>();
            for (Order o :
                    list) {
                String time = timeUtil.getTime(o.getDate());
                o.setDate(time);
            }
            pageBean.setRows(list);
            pageBean.setTotalCount(allCount);
            return pageBean;
        }
        return null;
    }

    @Override
    public PageBean<Order> getByStatus(String token, int status, int page, int size) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if ("admin".equals(subject)) {
            List<Order> list = orderDao.getByStatus(status, (page - 1) * size, size);
            int allCount = orderDao.getByStatusCount(status);
            PageBean<Order> pageBean = new PageBean<>();
            for (Order o :
                    list) {
                String time = timeUtil.getTime(o.getDate());
                o.setDate(time);
            }
            pageBean.setRows(list);
            pageBean.setTotalCount(allCount);
            return pageBean;
        }
        return null;
    }

    @Override
    public boolean update(String token, Order order) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if (order.getStatus() == -1) {
            Shop shop = new Shop();
            shop.setUid(order.getShopId());
            shop.setCount(order.getCount());
            int i = shopDao.addCount(shop);
            if (i == 1) {
                return orderDao.update(order) == 1;
            }
            return false;
        } else if (order.getStatus() == 0) {
            return orderDao.update(order) == 1;
        } else {
            return orderDao.update(order) == 1;
        }
    }

    @Override
    public boolean refund(String token, Order order) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if (!"admin".equals(subject)) {
            return orderDao.refund(order) == 1;
        }
        return false;
    }

    @Override
    public boolean add(String token, Order order) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if (!"admin".equals(subject)) {
            order.setUserId(Integer.valueOf(subject));
            Shop shop = new Shop();
            shop.setCount(order.getCount());
            shop.setUid(order.getShopId());
            int i = shopDao.updateCount(shop);
            if (i == 1) {
                return orderDao.insert(order) == 1;
            }
//            System.out.println(order.toString());
            return false;
        }
        return false;
    }
}
